import tkinter as tk
import random

class TetrisGame:
    def __init__(self, master):
        self.master = master
        self.master.title("Python俄罗斯方块")
        self.master.configure(bg='black')
        self.running = True  # 游戏运行状态标识
        
        # 游戏参数
        self.width = 10
        self.height = 20
        self.cell_size = 30
        
        # 创建游戏画布
        # 创建主游戏画布
        self.game_frame = tk.Frame(master, bg='black',width=self.width*self.cell_size)
        self.game_frame.pack(side='left')
        
        self.canvas = tk.Canvas(self.game_frame, 
                              width=self.width*self.cell_size,
                              height=self.height*self.cell_size,
                              bg='#1A1A1A',
                              highlightthickness=0,
                              borderwidth=0)
        self.canvas.pack()
        
        # 创建右侧控制面板
        self.control_frame = tk.Frame(master, bg='black', width=self.width*self.cell_size)
        self.control_frame.pack(side='right', padx=20, fill='both', expand=True)
        
        # 下一个方块预览画布
        self.preview_canvas = tk.Canvas(self.control_frame, 
                                      width=120, 
                                      height=120,
                                      bg='black',
                                      highlightthickness=0,
                                      borderwidth=0)
        self.preview_canvas.pack(pady=20)
        
        # 初始化游戏区域
        self.board = [[None] * self.width for _ in range(self.height)]
        
        # 定义方块形状
        self.shapes = [
            [[1,1,1,1]],  # I型
            [[1,1],[1,1]],  # O型
            [[1,1,1],[0,1,0]],  # T型
            [[1,1,1],[1,0,0]],  # L型
            [[1,1,1],[0,0,1]],  # J型
            [[1,1,0],[0,1,1]],  # S型
            [[0,1,1],[1,1,0]]   # Z型
        ]
        self.colors = ['#00FFFF', '#FFFF00', '#FF00FF', '#FFA500', '#0000FF', '#00FF00', '#FF0000']
        
        # 当前方块属性
        self.current_shape = None
        self.current_color = None
        self.current_x = 0
        self.current_y = 0
        
        # 分数显示
        self.score = 0
        # 分数显示（右侧底部）
        self.score_label = tk.Label(self.control_frame, 
                                  text=f"分数: {self.score}",
                                  font=('Arial', 20),
                                  fg='white',
                                  bg='#1A1A1A',
                                  width=15)
        self.score_label.pack(side='bottom', pady=20)
        
        # 绑定键盘事件
        self.master.bind('<Left>', lambda e: self.move(-1))
        self.master.bind('<Right>', lambda e: self.move(1))
        self.master.bind('<Down>', self.drop)
        self.master.bind('<Up>', self.rotate)
        
        # 开始游戏
        self.new_piece()
        self.update()

    def draw_preview(self):
        """绘制下一个方块预览"""
        self.preview_canvas.delete('preview')
        cell_size = 30
        offset_x = (120 - len(self.next_shape[0])*cell_size) // 2
        offset_y = (120 - len(self.next_shape)*cell_size) // 2
        
        for y, row in enumerate(self.next_shape):
            for x, cell in enumerate(row):
                if cell:
                    x1 = offset_x + x * cell_size
                    y1 = offset_y + y * cell_size
                    x2 = x1 + cell_size - 2
                    y2 = y1 + cell_size - 2
                    self.preview_canvas.create_rectangle(x1, y1, x2, y2,
                                                       fill=self.next_color,
                                                       outline='',
                                                       tags='preview')
    
    def new_piece(self):
        """生成新方块"""
        if not self.running:
            return
        # 生成当前和下一个方块
        if not hasattr(self, 'next_shape'):
            idx = random.randint(0, len(self.shapes)-1)
            self.next_shape = self.shapes[idx]
            self.next_color = self.colors[idx]
        
        self.current_shape = self.next_shape
        self.current_color = self.next_color
        idx = random.randint(0, len(self.shapes)-1)
        self.next_shape = self.shapes[idx]
        self.next_color = self.colors[idx]
        self.draw_preview()
        self.current_x = self.width//2 - len(self.current_shape[0])//2
        self.current_y = 0

        # 初始位置碰撞检测
        if self.collision(0, 0):
            self.game_over()
            return

    def draw_piece(self):
        """绘制当前方块"""
        self.canvas.delete('current')
        for y, row in enumerate(self.current_shape):
            for x, cell in enumerate(row):
                if cell:
                    x1 = (self.current_x + x) * self.cell_size
                    y1 = (self.current_y + y) * self.cell_size
                    x2 = x1 + self.cell_size
                    y2 = y1 + self.cell_size
                    self.canvas.create_rectangle(x1, y1, x2, y2,
                                                fill=self.current_color,
                                                tags='current')

    def update(self):
        """游戏主循环"""
        if not self.running:
            return
        
        if not self.collision(0, 1):
            self.current_y += 1
        else:
            self.merge_piece()
            self.clear_lines()
            self.new_piece()
        
        self.draw_board()
        self.draw_piece()
        self.master.after(1000, self.update)

    def collision(self, dx, dy, shape=None):
        if shape is None:
            shape = self.current_shape
        """碰撞检测"""
        for y, row in enumerate(self.current_shape):
            for x, cell in enumerate(row):
                if cell:
                    new_x = self.current_x + x + dx
                    new_y = self.current_y + y + dy
                    if new_x < 0 or new_x >= self.width:
                        return True
                    if new_y >= self.height:
                        return True
                    if new_y >=0 and self.board[new_y][new_x]:
                        return True
        return False

    def merge_piece(self):
        """合并方块到游戏板"""
        for y, row in enumerate(self.current_shape):
            for x, cell in enumerate(row):
                if cell:
                    if self.current_y + y < 0:  # 方块出现在可视区域上方时游戏结束
                        self.game_over()
                        return
                    self.board[self.current_y + y][self.current_x + x] = self.current_color

    def clear_lines(self):
        """消除完整行"""
        lines_cleared = 0
        for y in range(self.height):
            if all(self.board[y]):
                del self.board[y]
                self.board.insert(0, [None]*self.width)
                lines_cleared += 1
        
        if lines_cleared:
            self.score += lines_cleared * 100
            self.score_label.config(text=f"分数: {self.score}")

    def move(self, dx):
        """左右移动"""
        if not self.collision(dx, 0):
            self.current_x += dx
            self.draw_piece()

    def drop(self, event):
        """快速下落"""
        while not self.collision(0, 1):
            self.current_y += 1
        self.draw_piece()

    def rotate(self, event):
        """旋转方块"""
        rotated = list(zip(*reversed(self.current_shape)))
        if not self.collision(0, 0, rotated):
            self.current_shape = rotated
            self.draw_piece()

    def game_over(self):
        """游戏结束"""
        self.running = False
        from tkinter import messagebox
        messagebox.showinfo("游戏结束", f"最终得分: {self.score}")
        self.master.unbind('<Left>')
        self.master.unbind('<Right>')
        self.master.unbind('<Down>')
        self.master.unbind('<Up>')

    def draw_board(self):
        """绘制所有已落下的方块"""
        self.canvas.delete('board')
        for y in range(self.height):
            for x in range(self.width):
                if self.board[y][x]:
                    x1 = x * self.cell_size
                    y1 = y * self.cell_size
                    x2 = x1 + self.cell_size
                    y2 = y1 + self.cell_size
                    self.canvas.create_rectangle(x1, y1, x2, y2,
                                                fill=self.board[y][x],
                                                tags='board')

if __name__ == "__main__":
    root = tk.Tk()
    game = TetrisGame(root)
    root.mainloop()